package com.basin.auth.core.context;

import cn.hutool.core.util.ObjectUtil;
import com.basin.auth.common.enums.PlatformEnum;
import com.basin.auth.core.strategy.LoginStrategy;
import com.basin.auth.core.strategy.impl.DefaultLoginStrategy;
import com.basin.auth.core.strategy.impl.PhoneLoginStrategy;
import com.basin.auth.core.strategy.impl.UPLoginStrategy;
import com.basin.common.core.exception.BasinAssert;
import com.basin.common.core.exception.BasinException;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author: Sam ZHONG | sammy1997@aliyun.com
 */
@Component
@RequiredArgsConstructor
public class LoginContext {
    private static final String UP = "1";
    private static final String PHONE = "2";
    // 策略集合
    private final Map<PlatformEnum, Map<String, LoginStrategy>> strategies = new HashMap<>();

    private final UPLoginStrategy upLoginStrategy;
    private final PhoneLoginStrategy phoneLoginStrategy;

    @PostConstruct
    private void initialize() {
        // admin
        strategies.put(PlatformEnum.ADMIN,
                Map.of(UP, upLoginStrategy, PHONE, phoneLoginStrategy));
        // application
    }

    /**
     * 登录
     *
     * @param platform  平台
     * @param loginType 类型
     * @param object    参数
     * @return token
     */
    public String doLogin(PlatformEnum platform, String loginType, Object object) {
        Optional<Map<String, LoginStrategy>> opVal = Optional.of(this.strategies.get(platform));
        AtomicReference<String> token = new AtomicReference<>();
        opVal.ifPresentOrElse(
                val -> token.set(val.getOrDefault(loginType, new DefaultLoginStrategy()).login(object)),
                () -> {
                    throw new BasinException("未正确匹配登录平台，请联系客服或管理员");
                }
        );
        String tv = token.get();
        BasinAssert.isTrue(ObjectUtil.isNotEmpty(tv), "登录异常，返回TOKEN为空");
        // todo 登录记录存储
        return tv;
    }
}
